package com.huike.report.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.huike.business.mapper.TbBusinessMapper;
import com.huike.clues.domain.vo.IndexStatisticsVo;
import com.huike.clues.mapper.SysDictDataMapper;
import com.huike.clues.mapper.TbClueMapper;
import com.huike.common.core.page.TableDataInfo;
import com.huike.clues.domain.vo.ClueReportVo;
import com.huike.report.domain.ClueChang;
import com.github.pagehelper.PageHelper;
import com.huike.common.core.page.TableDataInfo;

import com.huike.report.domain.dto.ContractDto;
import com.huike.report.domain.dto.PageDto;
import com.huike.report.domain.vo.*;

import org.apache.commons.lang3.StringUtils;
import com.huike.report.mapper.ChannelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.huike.contract.mapper.TbContractMapper;
import com.huike.report.mapper.ReportMapper;
import com.huike.report.service.IReportService;

@Service
public class ReportServiceImpl implements IReportService {

    @Autowired
     private TbContractMapper tbContractMapper;
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;


    @Autowired
    private TbClueMapper tbClueMapper;
    @Autowired
    private TbBusinessMapper tbBusinessMapper;


    /**
     * *************看我看我**************
     * 传入两个时间范围，返回这两个时间范围内的所有时间，并保存在一个集合中
     * @param beginTime
     * @param endTime
     * @return
     * @throws ParseException
     */
    public static List<String> findDates(String beginTime, String endTime)
            throws ParseException {
        List<String> allDate = new ArrayList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Date dBegin = sdf.parse(beginTime);
        Date dEnd = sdf.parse(endTime);
        allDate.add(sdf.format(dBegin));
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            allDate.add(sdf.format(calBegin.getTime()));
        }
        System.out.println("时间==" + allDate);
        return allDate;
    }


    /**
     * ************看我看我***********
     * 用我能少走很多路
     * 我是用来机选百分比的方法
      * @param all
     * @param num
     * @return
     */
    private BigDecimal getRadio(Integer all,Long num) {
        if(all.intValue()==0){
            return new BigDecimal(0);
        }
        BigDecimal numBigDecimal = new BigDecimal(num);
        BigDecimal allBigDecimal = new BigDecimal(all);
        BigDecimal divide = numBigDecimal.divide(allBigDecimal,4,BigDecimal.ROUND_HALF_UP);
        return divide.multiply(new BigDecimal(100));
    }


    /**
     * 销量统计时间列表
     * @param begin
     * @param end
     * @return
     */
    @Override
    public LineChartVO salesStatistics(String begin, String end) throws ParseException {

        //存放begin到end每天对应的日期
        List<String> xAxisList = findDates(begin, end);

        //每天的销售额
        List<LineSeriesVO> seriesList = new ArrayList<>();

        List<Object> data = new ArrayList<>();
        // select sum(contract_order) from tb_contrant where create_time>? and create_time<?
        LineSeriesVO lineSeriesVO = new LineSeriesVO();
        lineSeriesVO.setName("每日销售统计");
        for (String xAxi : xAxisList) {

            LocalDate localDate = LocalDate.parse(xAxi);
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);

            Map map = new HashMap();
            map.put("beginTime",beginTime);
            map.put("endTime",endTime);
            //合同(contract)状态为4  status=4  (已完成)  才算销售出去
            Double  seriesCount= tbContractMapper.salesStatistics(map);

            seriesCount=seriesCount==null? 0.0:seriesCount;
            data.add(seriesCount);
            lineSeriesVO.setData(data);
        }
        seriesList.add(lineSeriesVO);


        LineChartVO lineChartVO = new LineChartVO();
        lineChartVO.setxAxis(xAxisList);
        lineChartVO.setSeries(seriesList);
        return lineChartVO;

    }
    /**
     * 销量统计 归属部门
     * @param pageNum
     * @param pageSize
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */

    @Override
    public TableDataInfo deptStatisticsList(Integer pageNum, Integer pageSize, LocalDate beginCreateTime, LocalDate endCreateTime) {
        //设置分页参数
        PageHelper.startPage(pageNum,pageSize);
        //把 日期localdate格式  转化成 localdateTime格式
        LocalDateTime beginTime = LocalDateTime.of(beginCreateTime, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(endCreateTime, LocalTime.MAX);

       Page<DeptContractVO> page = reportMapper.deptStatisticsList(beginTime,endTime);

        List<DeptContractVO> pageResult = page.getResult();
        //封装返回数据
        TableDataInfo tableDataInfo = new TableDataInfo();

            tableDataInfo.setRows(pageResult);
            tableDataInfo.setTotal(page.getTotal());
            tableDataInfo.setCode(200);
            tableDataInfo.setMsg("查询成功");
            tableDataInfo.setParams(null);

        return tableDataInfo;
    }

    /**
     * 销量统计  归属人
     * @param pageNum
     * @param pageSize
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public TableDataInfo ownerShipStatisticsList(Integer pageNum, Integer pageSize, LocalDate beginCreateTime, LocalDate endCreateTime) {
        //设置分页参数
        PageHelper.startPage(pageNum,pageSize);
        //把 日期localdate格式  转化成 localdateTime格式
        LocalDateTime beginTime = LocalDateTime.of(beginCreateTime, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(endCreateTime, LocalTime.MAX);

        Page<SuoShuRenContractVO> page = reportMapper.ownerShipStatisticsList(beginTime,endTime);

         List<SuoShuRenContractVO> pageResult = page.getResult();
        //封装返回数据
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(pageResult);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(200);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setParams(null);

        return tableDataInfo;
    }

    /**
     * 销量统计  归属渠道
     * @param pageNum
     * @param pageSize
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public TableDataInfo channelStatisticsList(Integer pageNum, Integer pageSize, LocalDate beginCreateTime, LocalDate endCreateTime) {
       //设置分页参数
        PageHelper.startPage(pageNum,pageSize);
        //把 日期localdate格式  转化成 localdateTime格式
        LocalDateTime beginTime = LocalDateTime.of(beginCreateTime, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(endCreateTime, LocalTime.MAX);

        Page<ChannelStatisticsVO> page = reportMapper.channelStatisticsList(beginTime,endTime);
        List<ChannelStatisticsVO> pageRsult= page.getResult();

         //遍历List<ChannelStatisticsVO>集合
        for (ChannelStatisticsVO channelStatisticsVO : pageRsult) {
             //get 出 归属渠道的值  0线上活动   1推广活动
            String channel = channelStatisticsVO.getChannel();
            if (channel != null && channel.length() > 0) {
                //select * from sys_dict_data  where dict_type = clues_item and dict_value=channel
                channel = sysDictDataMapper.SelectChannel(channel);
                channelStatisticsVO.setChannel(channel);
            }else {
                channelStatisticsVO.setChannel("面议直签");
            }

        }
        //封装返回数据
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(pageRsult);
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setCode(200);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setParams(null);

        return tableDataInfo;
    }


    @Autowired
    private ChannelMapper channelMapper;

    /**
     * 渠道统计饼图
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<ChanelAndNumVo> chanelStatistics(String beginCreateTime, String endCreateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate begin = LocalDate.parse(beginCreateTime, formatter);
        LocalDate end = LocalDate.parse(endCreateTime, formatter);
        //开始时间
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        //结束时间
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        //查询字典 数据是线上活动的信息
        List<sysDictDateVo> sysDictDateVos=channelMapper.selectDictDate();


        //调用mapper层去查询在这个时间段的活动渠道及其数量
        List<ChanelAndNumVo> chanelAndNumVoList=reportMapper.chanelStatistics(beginTime,endTime);
        //判断渠道来源
        for (sysDictDateVo dictDateVo : sysDictDateVos) {
            for (ChanelAndNumVo chanelAndNumVo : chanelAndNumVoList) {
                //如果字典的键值包含渠道来源就把字典标签写进去
                if (dictDateVo.getDictValue().equals(chanelAndNumVo.getChannel())){
                    chanelAndNumVo.setChannel(dictDateVo.getDictLabel());
                }
            }
        }
        return chanelAndNumVoList;
    }

    @Override
    public IndexVo index(String beginCreateTime, String endCreateTime) {
        IndexVo indexVo = new IndexVo();
        indexVo.setCluesNum(reportMapper.getcluesNums(beginCreateTime, endCreateTime));//线索数量
        indexVo.setBusinessNum(reportMapper.getEffectiveCluesNums(beginCreateTime, endCreateTime));//商机数量
        indexVo.setContractNum(reportMapper.getContractNums(beginCreateTime, endCreateTime));//客户数量
        indexVo.setSalesAmount(reportMapper.getSalesAmount(beginCreateTime, endCreateTime));//销售金额
        indexVo.setTofollowedCluesNum(reportMapper.getTofollowedCluesNum(beginCreateTime, endCreateTime));//待跟进线索数量
        indexVo.setTofollowedBusinessNum(reportMapper.getTofollowedBusinessNum(beginCreateTime, endCreateTime));//待跟进商机数量
        indexVo.setToallocatedCluesNum(reportMapper.getToallocatedCluesNum(beginCreateTime, endCreateTime));//待分配线索
        indexVo.setToallocatedBusinessNum(reportMapper.getToallocatedBusinessNum(beginCreateTime, endCreateTime));//待分配商机
        LocalDate now = LocalDate.now();
        LocalDateTime beginTime = LocalDateTime.of(now, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MAX);
        indexVo.setTodayCluesNum(reportMapper.getTodayCluesNum(beginTime, endTime));//今日新增线索数量
        indexVo.setTodayBusinessNum(reportMapper.getTodayBusinessNum(beginTime, endTime));//今日新增商机数量
        indexVo.setTodayContractNum(reportMapper.getTodayContractNum(beginTime, endTime));//今日新增客户数量
        indexVo.setTodaySalesAmount(reportMapper.getTodaySalesAmount(beginTime, endTime));//今日新增销售额

        return indexVo;
    }

    @Override
    public List<Map<String, Object>> salesStatistic(IndexStatisticsVo statisticsVo) {
        Integer allClues = tbClueMapper.countAllClues(statisticsVo.getBeginCreateTime(), statisticsVo.getEndCreateTime());
        List<Map<String, Object>> list = tbClueMapper.countAllClueByUser(statisticsVo);
        for (Map<String, Object> map : list) {
            Long num = (Long) map.get("num");
            map.put("radio", getRadio(allClues, num));
        }
        return list;
    }

    @Override
    public List<Map<String, Object>> businessChangeStatistics(IndexStatisticsVo statisticsVo) {
        Integer allClues = tbBusinessMapper.countAllBusiness(statisticsVo.getBeginCreateTime(), statisticsVo.getEndCreateTime());
        List<Map<String, Object>> list = tbBusinessMapper.countAllContractByUser(statisticsVo);
        for (Map<String, Object> map : list) {
            Long num = (Long) map.get("num");
            map.put("radio", getRadio(allClues, num));
        }
        return list;
    }

    @Override
    public VulnerabilityMapVo reportloudou(String beginCreateTime, String endCreateTime) {
        VulnerabilityMapVo vulnerabilityMapVo = new VulnerabilityMapVo();
        vulnerabilityMapVo.setCluesNums(reportMapper.getcluesNums(beginCreateTime, endCreateTime));
        vulnerabilityMapVo.setEffectiveCluesNums(reportMapper.getEffectiveCluesNums(beginCreateTime, endCreateTime));
        vulnerabilityMapVo.setBusinessNums(reportMapper.getBusinessNums(beginCreateTime, endCreateTime));
        vulnerabilityMapVo.setContractNums(reportMapper.getContractNums(beginCreateTime, endCreateTime));
        return vulnerabilityMapVo;
    }

    @Override
    public LineChartVO selectAllClient(String beginCreateTime, String endCreateTime) throws ParseException {
        List<String> dateList = findDates(beginCreateTime, endCreateTime);

        ArrayList<Object> newClientList = new ArrayList<>();
        ArrayList<Object> allClientList = new ArrayList<>();
        LineSeriesVO newClient = new LineSeriesVO();
        LineSeriesVO allClient = new LineSeriesVO();
        ArrayList<LineSeriesVO> lineSeriesVOS = new ArrayList<>();

        for (String s : dateList) {

            LocalDate date = LocalDate.parse(s);
            LocalDateTime tempBeginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime tempEndTime = LocalDateTime.of(date, LocalTime.MAX);

            Integer allClientCount = getClientCount(null, tempEndTime);
            Integer newClientCount = getClientCount(tempBeginTime, tempEndTime);

            newClientList.add(newClientCount);
            allClientList.add(allClientCount);

        }
        newClient.setName("新增用户数");
        newClient.setData(newClientList);

        allClient.setName("客户总数");
        allClient.setData(allClientList);

        lineSeriesVOS.add(newClient);
        lineSeriesVOS.add(allClient);

//数据封装
        LineChartVO lineChartVO = new LineChartVO();
        lineChartVO.setxAxis(dateList);
        lineChartVO.setSeries(lineSeriesVOS);
        return lineChartVO;
    }



    @Override
    public TableDataInfo selectByConditional(PageDto pageDto) {
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());

        TableDataInfo tableDataInfo = new TableDataInfo();

        LocalDateTime star = LocalDateTime.of(pageDto.getBeginCreateTime(), LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(pageDto.getEndCreateTime(), LocalTime.MAX);


        ContractDto contractDto = new ContractDto();

        contractDto.setChannel(pageDto.getChannel());
        contractDto.setCreateBy(pageDto.getCreateBy());
        contractDto.setBeginCreateTime(star);
        contractDto.setEndCreateTime(end);
        contractDto.setDeptId(pageDto.getDeptId());
        contractDto.setPageNum(pageDto.getPageNum());
        contractDto.setPageSize(pageDto.getPageSize());

        List<ConditionalQueryVo> list = reportMapper.selectByConditional(contractDto);

        tableDataInfo.setTotal(list.size());

        tableDataInfo.setRows(list);

        tableDataInfo.setCode(200);

        tableDataInfo.setMsg("查询成功");

        return tableDataInfo;
    }

    @Override
    public List<ReportVo> subjectStatistics(String beginCreateTime, String endCreateTime) {
        List<ReportVo> data = reportMapper.subjectStatistics(beginCreateTime, endCreateTime);
        for (ReportVo vo : data) {
            String subject = vo.getSubject();
            String la = sysDictDataMapper.selectDictLabel("course_subject", subject);
            vo.setSubject(la);
        }
        return data;
    }

    @Override
    public List<ClueReportVo> cluesStatisticsList(String beginCreateTime, String endCreateTime) {
        List<ClueReportVo> clueReportVoList = tbClueMapper.selectTbClueForReport(beginCreateTime, endCreateTime);
        return clueReportVoList;
    }

    @Override
    public LineChartVO cluesStatistcsList(String beginCreateTime, String endCreateTime) throws ParseException{
        List<String> dateList = findDates(beginCreateTime, endCreateTime);

        ArrayList<Object> newClueList = new ArrayList<>();
        ArrayList<Object> allClueList = new ArrayList<>();
        LineSeriesVO newClue = new LineSeriesVO();
        LineSeriesVO allClue = new LineSeriesVO();
        ArrayList<LineSeriesVO> lineSeriesVOS = new ArrayList<>();

        for (String s : dateList) {

            LocalDate date = LocalDate.parse(s);
            LocalDateTime tempBeginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime tempEndTime = LocalDateTime.of(date, LocalTime.MAX);

            Integer allClientCount = getClientCount(null, tempEndTime);
            Integer newClientCount = getClientCount(tempBeginTime, tempEndTime);

            newClueList.add(newClientCount);
            allClueList.add(allClientCount);

        }
        newClue.setName("新增线索数");
        newClue.setData(newClueList);

        allClue.setName("线索总数");
        allClue.setData(allClueList);

        lineSeriesVOS.add(newClue);
        lineSeriesVOS.add(allClue);

        //数据封装
        LineChartVO lineChartVO = new LineChartVO();
        lineChartVO.setxAxis(dateList);
        lineChartVO.setSeries(lineSeriesVOS);
        return lineChartVO;
    }


    /**
     * 活动统计饼图
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<ActivityAndNameAndIdVo> activityStatistics(String beginCreateTime, String endCreateTime){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate begin = LocalDate.parse(beginCreateTime, formatter);
        LocalDate end = LocalDate.parse(endCreateTime, formatter);
        //开始时间
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        //结束时间
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<ActivityAndNameAndIdVo> activityAndNameAndIdVos=channelMapper.selectactivityStatistics(beginTime,endTime);
        return activityAndNameAndIdVos;
    }

    /**
     * 渠道统计报表
     * @param tbActicitys
     * @return
     */
    @Override
    public List<ActivityStatisticsVo> activityStatisticsList(TbActicitys tbActicitys) {

        List<ActivityStatisticsVo> activityStatisticsList=channelMapper.activityStatisticsList(tbActicitys);
        return activityStatisticsList;
    }
    //查询线索数
    private Integer getClientCount (LocalDateTime beginTime, LocalDateTime endTime){
        HashMap<String, Object> map = new HashMap<>();
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);

        Integer allClientCount = reportMapper.countByMap(map);
        return allClientCount;
    }


}